@file:Suppress("DEPRECATION")

package com.example.continuousupload

import android.app.ProgressDialog
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.support.annotation.IntRange
import com.dhy.xpreference.SingleInstance
import com.dhy.xpreference.requestFilePermission
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import java.io.IOException

class MainActivity : AppCompatActivity() {
    private lateinit var buffer: Buffer
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        requestFilePermission()
        buffer = SingleInstance.get(this)
        if (buffer.url != null) etUrl.setText(buffer.url)
        if (buffer.file != null) etFile.setText(buffer.file)
        buttonClearSetting.setOnClickListener {
            buffer.url = null
            buffer.file = null
            buffer.save(this)
            startActivity(Intent(this, MainActivity::class.java))
            finish()
        }
        buttonUpload.setOnClickListener { upload("/uploadFullFile") }
        buttonMultUpload.setOnClickListener {
            val total = getFile().length()
            val blockSize = total / 3
            val bs = blockSize / 1024
            val count = getBlockCount(total, blockSize)
            repeat(count) {
                multUpload("/multiPatchUpload", "${bs}kb", it + 1)
            }
        }
    }

    private fun getBlockCount(total: Long, blockSize: Long): Int {
        val count = total / blockSize
        return (count + if (total % blockSize == 0L) 0 else 1).toInt()
    }

    /**
     * 文件分片上传
     * */
    private fun multUpload(tail: String, blockSize: String, @IntRange(from = 1) blockIndex: Int) {
        val FILE_DATA = "application/octet-stream".toMediaTypeOrNull()!!
        val file = getFile()
        val fileBody = file.asRequestBody(FILE_DATA)

        val request = Request.Builder()
            .header("fileName", file.name)
            .header("totalSize", file.length().toString())
            .header("blockSize", blockSize)
            .header("blockIndex", blockIndex.toString())
            .post(fileBody)
            .url(etUrl.text.toString() + tail)
            .build()
        showProgressDialog()
        OkHttpClient().newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
                runOnUiThread { dismissProgressDialog(true) }
                println("onFailure")
            }

            override fun onResponse(call: Call, response: Response) {
                runOnUiThread { dismissProgressDialog() }
                println("onResponse")
            }
        })
    }

    /**
     * 文件整体上传
     * */
    private fun upload(tail: String) {
        val FILE_DATA = "application/octet-stream".toMediaTypeOrNull()!!
        val file = getFile()
        val fileBody = file.asRequestBody(FILE_DATA)

        val request = Request.Builder()
            .header("fileName", file.name)
            .post(fileBody)
            .url(etUrl.text.toString() + tail)
            .build()
        showProgressDialog()
        OkHttpClient().newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
                runOnUiThread { dismissProgressDialog(true) }
                println("onFailure")
            }

            override fun onResponse(call: Call, response: Response) {
                runOnUiThread { dismissProgressDialog() }
                println("onResponse")
            }
        })
    }

    private fun getFile(): File {
        val sd = Environment.getExternalStorageDirectory()
        return File(sd, etFile.text.toString())
    }

    override fun onDestroy() {
        super.onDestroy()
        buffer.url = etUrl.text.toString()
        buffer.file = etFile.text.toString()
        buffer.save(this)
    }

    private var dialog: ProgressDialog? = null
    var showCount = 0
    private fun showProgressDialog() {
        if (dialog == null) dialog = ProgressDialog.show(this, "", "")
        else dialog!!.show()
        showCount++
    }

    private fun dismissProgressDialog(error: Boolean = false) {
        showCount--
        if (showCount == 0 || error) {
            showCount = 0
            dialog?.dismiss()
        }
    }
}

data class Buffer(var url: String? = null, var file: String? = null) : SingleInstance()
